package com.question.business.user.service.impl;

import com.question.business.auth.model.dto.UserDetailDTO;
import com.question.business.menu.service.IMenuService;
import com.question.business.user.entity.User;
import com.question.business.user.service.IUserRoleService;
import com.question.business.user.service.IUserService;
import com.question.common.constants.NumberConstants;
import com.question.common.enums.YesAndNoEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * s
 *
 * @author star
 * @since 2022/8/12
 */

@Slf4j
@Service
@AllArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private IUserService userService;

    private IUserRoleService userRoleService;

    private IMenuService menuService;

    /**
     * 用户名称登陆
     *
     * @param username 用户名称
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Assert.hasText(username, "用户名称不能为空");
        User user = userService.queryUserByUsername(username);
        Assert.notNull(user, "用户不存在");
        UserDetailDTO userDetail = new UserDetailDTO();
        userDetail.setId(user.getId());
        userDetail.setUsername(user.getUsername());
        userDetail.setNickName(user.getNickName());
        userDetail.setRoles(userRoleService.queryRoleByUserId(user.getId()));
        userDetail.setMenuCodes(menuService.queryMenuCodesByRoleId(userDetail.getRoles()));
        userDetail.setPassword(user.getPassword());
        userDetail.setEnabled(YesAndNoEnum.YES.getCode().equals(user.getEnabled()));
        userDetail.setLocked(true);
        // 错误次数超过3次
        if (Objects.nonNull(user.getLastLoginTime()) && user.getErrorNumber() >= NumberConstants.THREE) {
            LocalDateTime now = LocalDateTime.now();
            long diff = Duration.between(user.getLastLoginTime(), now).toHours();
            if (diff < 1) {
                userDetail.setLocked(false);
            } else {
                userService.unlockUser(user.getId());
            }
        }
        return userDetail;
    }

}
